﻿using System;
using System.IO;
using AgileNYCWebService.Manager.Data.Table;
using PushSharp;
using PushSharp.Android;
using PushSharp.Apple;
using PushSharp.Core;

namespace AgileNYCWebService.Manager.Data
{
    internal class NotificationManager
    {
        private readonly PushBroker _push;

        public NotificationManager()
        {
            _push = new PushBroker();

            //Wire up the events for all the services that the broker registers
            _push.OnNotificationSent += NotificationSent;
            _push.OnChannelException += ChannelException;
            _push.OnServiceException += ServiceException;
            _push.OnNotificationFailed += NotificationFailed;
            _push.OnDeviceSubscriptionExpired += DeviceSubscriptionExpired;
            _push.OnDeviceSubscriptionChanged += DeviceSubscriptionChanged;
            _push.OnChannelCreated += ChannelCreated;
            _push.OnChannelDestroyed += ChannelDestroyed;
        }

        public void SendNotificationToAndroid(Users userDetails, bool isReply, bool replyResult, int userCode)
        {
            try
            {
                //Configure and start Android GCM
                //IMPORTANT: The API KEY comes from your Google APIs Console App, under the API Access section, 
                //  by choosing 'Create new Server key...'
                //  You must ensure the 'Google Cloud Messaging for Android' service is enabled in your APIs Console
                _push.RegisterGcmService(new GcmPushChannelSettings("AIzaSyC9JX4bo3bV6DH6AHEtTiY9KTYvKPhgXw4"));
                //Fluent construction of an Android GCM Notification
                //IMPORTANT: For Android you MUST use your own RegistrationId here that gets generated within your Android app itself!
                GcmNotification notification = new GcmNotification().ForDeviceRegistrationId(userDetails.DeviceId);

                if (notification.IsValidDeviceRegistrationId())
                {
                    string alert = userCode + ";" + userDetails.FirstName + " " + userDetails.LastName + ";" + userDetails.Code;
                    if (isReply)
                        alert = userCode + ";" + replyResult.ToString();

                    _push.QueueNotification(notification
                        .WithJson("{\"alert\":\"" + alert + "\",\"badge\":1,\"sound\":\"sound.caf\"}"));

                }
                _push.StopAllServices();
            }
            catch (Exception ex)
            {
                Logger.Log.Error("Notification send android ->", ex);
            }
        }

        public void SendNotificationToApple(Users userDetails, bool isReply, bool replyResult)
        {
            //Configure and start Apple APNS
            // IMPORTANT: Make sure you use the right Push certificate.  Apple allows you to generate one for connecting to Sandbox,
            //   and one for connecting to Production.  You must use the right one, to match the provisioning profile you build your
            //   app with!
            var appleCert = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data/AgileNYC.p12"));
            //IMPORTANT: If you are using a Development provisioning Profile, you must use the Sandbox push notification server 
            //  (so you would leave the first arg in the ctor of ApplePushChannelSettings as 'false')
            //  If you are using an AdHoc or AppStore provisioning profile, you must use the Production push notification server
            //  (so you would change the first arg in the ctor of ApplePushChannelSettings to 'true')
#if DEBUG
            _push.RegisterAppleService(new ApplePushChannelSettings(false, appleCert, "pwd")); //Extension method
#else
            _push.RegisterAppleService(new ApplePushChannelSettings(true, appleCert, "pwd")); //Extension method
#endif
            //Fluent construction of an iOS notification
            //IMPORTANT: For iOS you MUST MUST MUST use your own DeviceToken here that gets generated within your iOS app itself when the Application Delegate
            //  for registered for remote notifications is called, and the device token is passed back to you
            string alert = userDetails.FirstName + " " + userDetails.LastName + " would like to Connect with you";
            if (isReply && replyResult)
                alert = userDetails.FirstName + " " + userDetails.LastName + " has confirmed your Connect Request";

            _push.QueueNotification(new AppleNotification()
                                       .ForDeviceToken(userDetails.DeviceId)
                //.ForDeviceToken("73117055537c0664d931189b2d77f6953c59e22f5c6981ce5bc72b95943bf75c")
                                       .WithPayload(new AppleNotificationPayload(alert, userDetails.Badge,"default")));
            _push.StopAllServices();

        }


        static void DeviceSubscriptionChanged(object sender, string oldSubscriptionId, string newSubscriptionId, INotification notification)
        {
            //Currently this event will only ever happen for Android GCM
            Logger.Log.Info("Device Registration Changed:  Old-> " + oldSubscriptionId + "  New-> " + newSubscriptionId + " -> " + notification);
        }

        static void NotificationSent(object sender, INotification notification)
        {
            Logger.Log.Info("Sent: " + sender + " -> " + notification);
        }

        static void NotificationFailed(object sender, INotification notification, Exception notificationFailureException)
        {
            Logger.Log.Error("Failure: " + sender + " -> " + notificationFailureException.Message + " -> " + notification);
        }

        static void ChannelException(object sender, IPushChannel channel, Exception exception)
        {
            Logger.Log.Error("Channel Exception: " + sender + " -> " + exception);
        }

        static void ServiceException(object sender, Exception exception)
        {
            Logger.Log.Error("Channel Exception: " + sender + " -> " + exception);
        }

        static void DeviceSubscriptionExpired(object sender, string expiredDeviceSubscriptionId, DateTime timestamp, INotification notification)
        {
            Logger.Log.Error("Device Subscription Expired: " + sender + " -> " + expiredDeviceSubscriptionId);
        }

        static void ChannelDestroyed(object sender)
        {
            Logger.Log.Error("Channel Destroyed for: " + sender);
        }

        static void ChannelCreated(object sender, IPushChannel pushChannel)
        {
            Logger.Log.Info("Channel Created for: " + sender);
        }
    }
}